package com.bestcem.xm.member.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.domain.web.XmResultJson;
import com.bestcem.xm.common.core.uitls.GRpcUtil;
import com.bestcem.xm.component.security.context.SecurityContextHolder;
import com.bestcem.xm.member.controller.param.project.CreateProjectRequest;
import com.bestcem.xm.member.controller.param.project.UpdateProjectRequest;
import com.bestcem.xm.member.controller.vo.FieldValueVO;
import com.bestcem.xm.member.controller.vo.ProjectVO;
import com.bestcem.xm.member.entity.mongo.ExtendFieldValue;
import com.bestcem.xm.member.enums.ExtendFieldTypeEnum;
import com.bestcem.xm.member.grpc.service.param.PageParam;
import com.bestcem.xm.member.grpc.service.param.project.*;
import com.bestcem.xm.member.service.ProjectService;
import com.bestcem.xm.member.service.dto.PageDTO;
import com.bestcem.xm.member.service.dto.ProjectDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author dc.wang <dc.wang@idiaoyan.com>
 * @version V1.0
 * @description 机构项目web接口
 * @date 2021/8/4
 */
@Slf4j
@RestController
@RequestMapping("/member/mprojects")
public class ProjectController {
    private final ProjectService projectService;

    @Autowired
    public ProjectController(ProjectService projectService) {
        this.projectService = projectService;
    }

    @GetMapping("/{id}")
    public XmResultJson<ProjectVO> getProjects(@PathVariable String id,
                                               HttpServletRequest request) {
        
        String orgId = SecurityContextHolder.getOrgId();
        
         String userId = SecurityContextHolder.getUserId();
        GetProjectParam param = new GetProjectParam();
        param.setId(id);
        param.setOrgId(orgId);
        param.setUserId(userId);
        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            return XmResultJson.fail(-1, violation.getMessage());
        }

        ServiceResult<ProjectDto> result = projectService.getProject(param);
        if (!result.isSuccess()) {
            log.error("请求异常：{},参数：{}", result.getMsg(), param);
            return XmResultJson.fail(-1, result.getMsg());
        }
        ProjectVO data = this.convertFrom(result.getData());

        return XmResultJson.success(data);
    }

    @GetMapping()
    public XmResultJson<PageDTO<ProjectVO>> listProjects(@RequestParam(name = "mid") String memberId,
                                                             @RequestParam(name = "page", required = false) Integer page,
                                                             @RequestParam(name = "rowsPerPage", required = false) Integer pageSize,
                                                             HttpServletRequest request) {
        
        String orgId = SecurityContextHolder.getOrgId();
        
         String userId = SecurityContextHolder.getUserId();
        // 兼容前端参数
        PageParam pageParam = new PageParam(Optional.ofNullable(page).orElse(1) - 1, Optional.ofNullable(pageSize).orElse(10));
        ListMemberProjectsParam param = new ListMemberProjectsParam(orgId, memberId, pageParam, userId);

        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            return XmResultJson.fail(-1, violation.getMessage());
        }

        ServiceResult<PageDTO<ProjectDto>> result = projectService.listMemberProjects(param);
        if (!result.isSuccess()) {
            log.error("请求异常：{},参数：{}", result.getMsg(), param);
            return XmResultJson.fail(-1, result.getMsg());
        }
        if (result.getData() == null || CollectionUtils.isEmpty(result.getData().getRows())) {
            return XmResultJson.success(new PageDTO<>(new ArrayList<>(0), 0));
        }
        List<ProjectVO> data = result.getData().getRows().stream().map(this::convertFrom).collect(Collectors.toList());

        return XmResultJson.success(new PageDTO<>(data, result.getData().getTotal()));
    }

    @PostMapping()
    public XmResultJson<String> createProject(@RequestBody CreateProjectRequest request,
                                                  HttpServletRequest httpServletRequest) {
        
        String orgId = SecurityContextHolder.getOrgId();
        String userId = SecurityContextHolder.getUserId();
        CreateProjectParam param = this.convertFrom(request);
        param.setOrgId(orgId);

        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            return XmResultJson.fail(-1, violation.getMessage());
        }

        ServiceResult<String> result = projectService.createProject(param);
        if (!result.isSuccess()) {
            log.error("请求异常：{},参数：{}", result.getMsg(), param);
            return XmResultJson.fail(-1, result.getMsg());
        }

        return XmResultJson.success(result.getData());
    }

    @PutMapping("/{id}")
    public XmResultJson<String> updateProject(@PathVariable String id,
                                                  @RequestBody UpdateProjectRequest request,
                                                  HttpServletRequest httpServletRequest) {
        
        String orgId = SecurityContextHolder.getOrgId();
        UpdateProjectParam param = this.convertFrom(request);
        param.setId(id);
        param.setOrgId(orgId);

        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            return XmResultJson.fail(-1, violation.getMessage());
        }

        ServiceResult<String> result = projectService.updateProject(param);
        if (!result.isSuccess()) {
            log.error("请求异常：{},参数：{}", result.getMsg(), param);
            return XmResultJson.fail(-1, result.getMsg());
        }

        return XmResultJson.success(result.getData());
    }

    @DeleteMapping("/{id}")
    public XmResultJson<Integer> deleteProject(@PathVariable("id") String id,
                                                   HttpServletRequest request) {

        
        String orgId = SecurityContextHolder.getOrgId();
        DeleteProjectParam param = new DeleteProjectParam(orgId, id);

        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            return XmResultJson.fail(-1, violation.getMessage());
        }

        ServiceResult<Integer> result = projectService.deleteById(param);
        if (!result.isSuccess()) {
            log.error("请求异常：{},参数：{}", result.getMsg(), param);
            return XmResultJson.fail(-1, result.getMsg());
        }

        return XmResultJson.success(result.getData());
    }

    private CreateProjectParam convertFrom(CreateProjectRequest request) {
        CreateProjectParam res = new CreateProjectParam();
        BeanUtil.copyProperties(request, res);
        return res;
    }

    private UpdateProjectParam convertFrom(UpdateProjectRequest request) {
        UpdateProjectParam res = new UpdateProjectParam();
        BeanUtil.copyProperties(request, res);
        return res;
    }

    private ProjectVO convertFrom(ProjectDto projectDto) {
        ProjectVO res = new ProjectVO();
        BeanUtils.copyProperties(projectDto, res);
        res.setContractMoney(projectDto.getContractMoney());
        if (!CollectionUtils.isEmpty(projectDto.getExtendFieldValues())) {
            List<FieldValueVO> fieldValueVOList = projectDto.getExtendFieldValues().stream().map(this::convertFrom).collect(Collectors.toList());
            res.setExtendFieldValues(fieldValueVOList);
        } else {
            // 兼容前端返回空集合
            res.setExtendFieldValues(new ArrayList<>(0));
        }
        return res;
    }

    private FieldValueVO convertFrom(ExtendFieldValue value) {
        FieldValueVO res = new FieldValueVO();
        res.setId(value.getFieldId());
        res.setName(value.getFieldName());
        res.setType(value.getFieldType());
        if (value.getFieldValue() == null) {
            return res;
        }

        // 获取扩展字段类型
        Object fieldValue = value.getFieldValue();
        if (ExtendFieldTypeEnum.DATETIME.matches(value.getFieldType())) {
            // 获取扩展字段值
            if (ObjectUtils.isNotEmpty(fieldValue)) {
                String dateStr = String.valueOf(fieldValue);
                DateTime date = cn.hutool.core.date.DateUtil.parse(dateStr);
                if (date != null) {
                    res.setValue(date.toString("yyyy/MM/dd"));
                }
            }
        } else {
            if (ObjectUtils.isNotEmpty(fieldValue)) {
                res.setValue(value.getFieldValue().toString());
            }
        }
        return res;
    }
}
